package com.dylan.历史.java8.lambda表达式;

import java.util.*;

/**
 * Created by Dylan on 2018/7/18.
 *
 * 匿名内部类和lambda表达式的相同点
 * 1. 可以访问"有效的final局部变量",不用声明为final变量,但是值不能改
 * 2. 都可以修改实例变量和静态变量
 * 匿名内部类和lambda表达式的不同点
 * 1. 匿名内部类this引用的是匿名内部类的实例
 *    lambda表达式this引用的是创建该匿名内部类的方法的this参数
 *
 * 自有变量: 不是参数且没有在代码中定义的变量
 * 闭包: 含有自有变量的代码块被称之为闭包
 */
public class 变量作用域 {

    static int i = 5;
    int[] count = new int[1];

    public static void main(String[] args) {
        List<String> list = Arrays.asList("D", "A", "E", "B", "C");
        System.out.println(new 变量作用域().sort1(list, true));
        System.out.println(new 变量作用域().sort1(list, false));
        System.out.println(new 变量作用域().sort2(list, true));
        System.out.println(new 变量作用域().sort2(list, false));
    }

    // 匿名内部类实现
    public List<String> sort1(List<String> list, boolean asc) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Collections.sort(list, new Comparator<String>() {
                    @Override
                    public int compare(String o1, String o2) {
                        // 局部变量不允许修改
                        //asc = !asc;
                        // 实例变量可以修改
                        count[0]++;
                        // 静态变量可以修改
                        i++;
                        // this表示匿名内部类的实例
                        System.out.println(this.getClass());
                        System.out.println(Arrays.toString(this.getClass().getInterfaces()));
                        return asc ? o1.compareTo(o2) : o2.compareTo(o1);
                    }
                });
            }
        }).start();
        return list;
    }

    // lambda表达式实现
    public List<String> sort2(List<String> list, boolean asc) {
        new Thread(() -> {
            Collections.sort(list, (o1, o2) -> {
                // 局部变量不允许修改
                //asc = !asc;
                // 实例变量可以修改
                count[0]++;
                // 静态变量可以修改
                i++;
                // this引用的是创建该匿名内部类的方法(sort2())的this参数
                System.out.println(this.getClass().getName());
                return asc ? o1.compareTo(o2) : o2.compareTo(o1);
            });
        }).start();
        return list;
    }
}
